package com.www.ve.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * <p>项目名称: zzw-tech </p>
 * <p>包名称: com.zzw.bridge.common.utils </p>
 * <p>描述: 日期处理 </p>
 * <p> 日期处理 </p>
 * <p>创建时间: 2022/11/14 17 </p>
 *
 * @author coco
 * @version v1.0
 */
public class DateUtils {
    /**
     * 时间格式(yyyy-MM-dd)
     */
    public final static String DATE_PATTERN = "yyyy-MM-dd";
    /**
     * 时间格式(HH:mm:ss)
     */
    public final static String DATE_TIME = "HH:mm:ss";
    /**
     * 时间格式(yyyy-MM-dd HH:mm:ss)
     */
    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    public static final String ZONE = "GMT+8";

    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 日期格式化 日期格式为：yyyy-MM-dd
     *
     * @param date 日期
     * @return 返回yyyy-MM-dd格式日期
     */
    public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    public static String localDateformat(LocalDateTime date, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

        return date.format(formatter);
    }

    /**
     * 字符串转换为LocalDateTime
     * 日期格式为： yyyy-MM-dd HH:mm:ss
     * @param dateTime
     * @return
     */
    public static LocalDateTime localDateTimeformat(String dateTime) {
        return LocalDateTime.parse(dateTime, DATE_TIME_FORMATTER);
    }

    /**
     * 日期格式化 日期格式为：yyyy-MM-dd
     *
     * @param date    日期
     * @param pattern 格式，如：DateUtils.DATE_TIME_PATTERN
     * @return 返回yyyy-MM-dd格式日期
     */
    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 日期解析
     *
     * @param date    日期
     * @param pattern 格式，如：DateUtils.DATE_TIME_PATTERN
     * @return 返回Date
     */
    public static Date parse(String date, String pattern) {
        try {
            return new SimpleDateFormat(pattern).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Double getDaysInTwoDate(LocalDateTime lastDate, LocalDateTime nowDate) {
        Duration duration = Duration.between(lastDate, nowDate);
        return BigDecimal.valueOf(duration.toMillis())
                .divide(BigDecimal.valueOf(1000), 6, RoundingMode.HALF_UP)
                .divide(BigDecimal.valueOf(60), 6, RoundingMode.HALF_UP)
                .divide(BigDecimal.valueOf(60), 6, RoundingMode.HALF_UP)
                .divide(BigDecimal.valueOf(24), 6, RoundingMode.HALF_UP)
                .doubleValue();
    }

    public static Double getDays(LocalDateTime lastDate, LocalDateTime nowDate) {
        Long daysDifference = ChronoUnit.DAYS.between(nowDate.toLocalDate(), lastDate.toLocalDate());
        // 将 long 类型的差异转换为 Double
        Double days = Double.valueOf(daysDifference);
        return days;
    }

    /**
     * 通过间隔时间生成时间点
     * @param totalMinutes
     * @param startTime
     * @param endTime
     * @return
     */
    public static List<String> generateLocalTime(int totalMinutes, LocalTime startTime, LocalTime endTime) {
        if (startTime == null || endTime == null) {
            throw new IllegalArgumentException("Start and end times must be specified.");
        }

        List<String> generatedTimes = new ArrayList<>();
        LocalTime currentTime = startTime;
        generatedTimes.add(currentTime.format(DateTimeFormatter.ofPattern("HH:mm")));

        Duration duration = Duration.ofMinutes(totalMinutes);
        while (currentTime.isBefore(endTime.minus(duration))) {
            currentTime = currentTime.plus(duration);
            generatedTimes.add(currentTime.format(DateTimeFormatter.ofPattern("HH:mm")));
        }

        generatedTimes.add(endTime.format(DateTimeFormatter.ofPattern("HH:mm")));

        // Assuming executeTimeList is a predefined list of times in the format "HH:mm"
        List<String> executeTimeList = new ArrayList<>(); // Example values

        List<String> result = new ArrayList<>();
        for (String time : generatedTimes) {
            if (!executeTimeList.contains(time) && !result.contains(time)) {
                result.add(time);
            }
        }

        result.addAll(executeTimeList);

        Collections.sort(result);

        // 最后一个为23:59 第一个为00:00 只差一分钟删掉
        result.remove(result.size() - 1);

        return result;
    }

    /**
     * 通过间隔时间生成时间点
     *
     * @param time      间隔时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public static List<String> generateLocalTime(LocalTime time, LocalTime startTime, LocalTime endTime) {
        List<LocalTime> generatedTimes = new ArrayList<>();
        LocalTime tmp = startTime;
        generatedTimes.add(tmp);

        int addHour = time.getHour();
        int addMinute = time.getMinute();

        while (tmp.isBefore(endTime.minusHours(addHour).minusMinutes(addMinute))) {
            tmp = tmp.plusHours(addHour).plusMinutes(addMinute);
            generatedTimes.add(tmp);
        }

        generatedTimes.add(endTime);

        List<String> result = new ArrayList<>();
        List<String> executeTimeList = new ArrayList<>();
        for (LocalTime item : generatedTimes) {
            String formattedTime = String.format("%02d:%02d", item.getHour(), item.getMinute());
            if (!executeTimeList.contains(formattedTime) && !result.contains(formattedTime)) {
                result.add(formattedTime);
            }
        }

        result.addAll(executeTimeList);
        Collections.sort(result);

        executeTimeList = result;
        return executeTimeList;
    }
}
